/**
 * 常用工具方法
 */
import { BASE_URL } from '@/constants/global.const';
import { message } from 'antd';
import { v4 as uuidv4 } from 'uuid';

// 数字按千分位格式化
export const formatCash = (num: number | string): string | number => {
  if (!num) return 0;
  return `${num}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};

/**
 * 防抖
 */
export const debounce = (fn: TAnyFunction, wait = 1000) => {
  let timer: any = null;
  return function debounceFn(this: any, ...args: any) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, wait);
  };
};

/**
 * 节流
 */
export const throttle = (fn: TAnyFunction, wait = 1000) => {
  let last: number;
  return function throttleFn(this: any, ...args: any) {
    const now = +new Date();
    if (!last || now - last > wait) {
      fn.apply(this, args);
      last = now;
    }
  };
};

/**
 * 复制内容到剪贴板
 * @param value 需要复制的内容
 * @returns
 */
export function copyToBoard(value: string): boolean {
  const element = document.createElement('textarea');
  document.body.appendChild(element);
  element.value = value;
  element.select();
  if (document.execCommand('copy')) {
    document.execCommand('copy');
    document.body.removeChild(element);
    return true;
  }
  document.body.removeChild(element);
  return false;
}

// 首字母转大写
export const firstToUpper = (str: string) => {
  if (typeof str !== 'string') {
    return str;
  }
  return str.replace(/^\S/, (s) => s.toUpperCase());
};

/**
 * 拼接url参数
 * @param params url参数
 * @returns
 */
export const makeQueryStr = (params = {}): string => {
  const queryStr: string[] = [];
  Object.keys(params).forEach((key) => {
    const item = params[key];
    queryStr.push(`${key}=${encodeURIComponent(item)}`);
  });
  return queryStr.join('&');
};

// 获取请求参数
export const getRequestParam = (url: string, obj: Record<string, string>) =>
  url + '?' + makeQueryStr(obj);

/**
 * 从链接下载文件
 * @param link 下载链接
 * @param filename 文件名
 * @param params 下载参数
 */
export const download = ({
  link,
  filename,
  params,
}: {
  link: string;
  filename: string;
  params: Record<string, any>;
}): void => {
  let name = filename;
  if (!name) {
    name = link.slice(link.lastIndexOf('/') + 1);
  }
  const url = getRequestParam(`${BASE_URL}${link}`, {
    ...params,
  });
  const eleLink = document.createElement('a');
  eleLink.style.display = 'none';
  eleLink.href = url;
  eleLink.download = `${name}`;
  document.body.appendChild(eleLink);
  eleLink.click();
  document.body.removeChild(eleLink);
};

/**
 * 带倒计时的message
 * @param content 显示的文字内容，倒计时时间需使用占位符###
 * @param duration 倒计时时间
 * @param key 消息的key，自动生成
 */
export const commonMessage = {
  success: ({ content, duration = 3, key, cb }: TMessageParams) => {
    let retDuration = duration;
    const retKey = key || uuidv4();
    const retContent = content.replace(/###/, `${duration}`);
    message.success({
      content: retContent,
      key: retKey,
      duration: retDuration,
      ...(cb && { onClose: cb }),
    });
    const timer = setTimeout(() => {
      retDuration--;
      if (retDuration <= 0) {
        clearTimeout(timer);
      } else {
        commonMessage.success({ content, duration: retDuration, key: retKey, cb });
      }
    }, 1000);
  },
};

// 自定义异步超时
export const timeoutReject = (promise: Promise<any>, time = 0) => {
  const timeoutPro = new Promise((resolve) => {
    setTimeout(() => resolve(null), time);
  });
  return Promise.race([promise, timeoutPro]);
};

// 一维数据转树形
export const toTree = (data: Record<string, any>[]) => {
  const cloneData = JSON.parse(JSON.stringify(data));
  return cloneData.filter((father: any) => {
    const branchArr = cloneData.filter((child: any) => father.id === child.pid);
    if (branchArr.length > 0) {
      father.children = branchArr;
    }
    return father.pid == 0; //返回第一层，视实际情况修改
  });
};

// 树形数据扁平化处理
export const flatData = (orgData: any[]) => {
  let deepth = 0; // 最大深度
  const dfs = (node: any, res = [], nodeGroup: string[] = []) => {
    nodeGroup.push(node.id);
    (res as any[]).push({
      deepth: nodeGroup.length,
      ...node,
    });
    deepth = Math.max(nodeGroup.length, deepth);
    if (node.children && node.children.length) {
      node.children.forEach((child: any) => dfs(child, res, nodeGroup));
    }
    nodeGroup.pop();
    return res;
  };
  const formattedData = orgData.reduce((res: any, item: any) => dfs(item, res), []);
  return formattedData;
};

/**
 * 判断是否是json字符串，限制为object
 * @param str
 * @returns boolean
 */
export const isJSONStr = (str: string) => {
  if (typeof str == 'string') {
    try {
      const obj = JSON.parse(str);
      if (typeof obj == 'object' && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }
  return false;
};

/**
 * 获取url所有参数
 * @param url string
 * @returns Object
 */
export const getAllUrlParams = (url: string) => {
  const pattern = /(\w+)=(\w+)/gi;
  const parames = {};
  url.replace(pattern, ($: string, $1: string, $2: string) => {
    parames[$1] = $2;
    return $2;
  });
  return parames;
};

// 根据当前数组生成最小id
export const generalMinId = (arr: any[]) => {
  const sortArr: any[] = arr.sort();
  let value = sortArr.findIndex((o, index) => o !== index + 1) + 1;
  if (value === 0) {
    // 没找到
    if (sortArr.length === 0) {
      value = 1;
    } else if (sortArr.length) {
      const len = sortArr.length;
      value = sortArr[len - 1] + 1;
    }
  }
  return value;
};

//搜索前条件删除
export const beforeSearchSubmit = (params: any) => {
  const obj: any = {};
  Object.keys(params).forEach((item: string) => {
    if (params[item] !== '') {
      obj[item] = params[item];
    }
  });
  return obj;
};

//表单手机号格式校验
export const checkPhone = (_: any, value: any) => {
  const reg = /^[1][3-9][0-9]{9}$/;
  if (value && !reg.test(value)) {
    return Promise.reject(new Error('请输入正确的手机号'));
  } else {
    return Promise.resolve();
  }
};
